package co.edu.unal.satacredito.mediation;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import co.edu.unal.satacredito.database.administration.ejb.EventLogDaoEJBLocal;
import co.edu.unal.satacredito.database.administration.ejb.MachineDaoEJBLocal;
import co.edu.unal.satacredito.database.administration.exceptions.DAOException;
import co.edu.unal.satacredito.database.constants.MachineConstants;
import co.edu.unal.satacredito.database.entity.EventLog;
import co.edu.unal.satacredito.database.entity.Machine;
import co.edu.unal.satacredito.infrastructure.dto.EventDTO;
import co.edu.unal.satacredito.infrastructure.dto.MachineDTO;

/**
 * Session Bean implementation class InfraestructureEJB
 */
@Stateless
public class InfraestructureEJB implements InfraestructureEJBRemote,
		InfraestructureEJBLocal {

	@EJB
	private MachineDaoEJBLocal machineDaoEJB;
	@EJB
	private MachinesUpEJBLocal machinesUpEJB;
	@EJB
	private EventLogDaoEJBLocal eventLogDAOEJB;

	private final static String ENABLED = "Activada";
	private final static String DISABLED = "Desactivada";
	private final static String VACANT = "Disponible";
	private final static String NO_VACANT = "Ocupada";
	private final static String DEAD = "Inalcanzable.";

	/**
	 * Default constructor.
	 */
	public InfraestructureEJB() {
	}

	@Override
	public void deactivate(String name) {
		try {
			Machine machine = machineDaoEJB.findByName(name);
			InetAddress in = InetAddress.getByName(machine.getMachineIP()); 
			if (in.isReachable(2000)) { 
				if (machine.getVacant() == MachineConstants.VACANT) {
					if (machine.getStatus() == MachineConstants.STATUS_ENABLED) {
						machine.setStatus(MachineConstants.STATUS_DISABLED);
					} else {
						machine.setStatus(MachineConstants.STATUS_ENABLED);
					}
					machineDaoEJB.updateMachine(machine.getId() + "", machine);
				} else {
					
				}
		    }else{
		    	
		    } 
		} catch (DAOException e) {
		} catch (UnknownHostException e) {
		} catch (IOException e) {
		}
	}

	@Override
	public List<EventDTO> getLog(String name) {
		List<EventLog> eventos = new ArrayList<EventLog>();
		List<EventDTO> retorna = new ArrayList<EventDTO>();
		Machine machine = new Machine();
		
		try {
			machine = machineDaoEJB.findByName(name);
			eventos = eventLogDAOEJB.findEventsByMachine(machine);
			
			for (EventLog eventsLog : eventos) {
				retorna.add(new EventDTO(eventsLog));
			}
			
			return retorna;
		} catch (Exception e) {
			return retorna;
		}
	}

	@Override
	public List<MachineDTO> getMachines() {
		List<Machine> machines = new ArrayList<Machine>();
		List<MachineDTO> machinesDTOs = new ArrayList<MachineDTO>();
		ArrayList<String> avalaibleIps = new ArrayList<String>();
		try {
			avalaibleIps = machinesUpEJB.ipsList();
			machines = machineDaoEJB.findAllMachines();
			if (avalaibleIps.size() == 0) {
				for (Machine machine : machines) {
					MachineDTO tempMachine = new MachineDTO();
					tempMachine.setIp(machine.getMachineIP());
					tempMachine.setName(machine.getMachineName());
					if (machine.getStatus() == MachineConstants.STATUS_ENABLED) {
						tempMachine.setState(ENABLED);
					} else {
						tempMachine.setState(DISABLED);
					}
					if (machine.getVacant() == MachineConstants.VACANT) {
						tempMachine.setActivity(VACANT);
					} else {
						tempMachine.setActivity(NO_VACANT);
					}
					machinesDTOs.add(tempMachine);
				}

			} else {
				for (Machine machine : machines) {
					MachineDTO tempMachine = new MachineDTO();
					tempMachine.setIp(machine.getMachineIP());
					tempMachine.setName(machine.getMachineName());
					if (avalaibleIps.contains(tempMachine.getIp())) {
						if (machine.getStatus() == MachineConstants.STATUS_ENABLED) {
							tempMachine.setState(ENABLED);
						} else {
							tempMachine.setState(DISABLED);
						}
						if (machine.getVacant() == MachineConstants.VACANT) {
							tempMachine.setActivity(VACANT);
						} else {
							tempMachine.setActivity(NO_VACANT);
						}
						machinesDTOs.add(tempMachine);
					} else {
						tempMachine.setState(DEAD);
						tempMachine.setActivity(VACANT);
						machine.setVacant(MachineConstants.VACANT);
						machine.setStatus(MachineConstants.STATUS_DISABLED);
						machineDaoEJB.updateMachine(machine.getId().toString(),
								machine);
						machinesDTOs.add(tempMachine);
					}

				}
			 }
			return machinesDTOs;
		} catch (DAOException e) {
			return machinesDTOs;
		}
	}

	@Override
	public boolean newMachine(MachineDTO machine) {
		if (machine.getIp().matches(
						"^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$")) {

			try {
				if (machineDaoEJB.findByIp(machine.getIp()) == null) {
					InetAddress in;
					in = InetAddress.getByName(machine.getIp());
					if (in.isReachable(2000)) {
						Machine newmachine = new Machine();
						newmachine.setMachineIP(machine.getIp());
						newmachine.setMachineName(machine.getName());
						if (machine.getState().equals("Activada")) {
							newmachine
									.setStatus(MachineConstants.STATUS_ENABLED);
						} else {
							newmachine
									.setStatus(MachineConstants.STATUS_DISABLED);
						}
						newmachine.setVacant(MachineConstants.VACANT);
						newmachine.setTypeMachine(MachineConstants.PROCESSING);
						machineDaoEJB.create(newmachine);
						return true;
					} else {
						return false;
					}
				} else {
					return false;
				}

			} catch (UnknownHostException e) {
				return false;
			} catch (IOException e) {
				return false;
			} catch (DAOException e) {
				return false;
			}
		} else {
			return false;
		}
	}

}
